<template>
	<!-- @touchmove.stop.prevent -->
	<view class="tui-drawer">
		<view v-if="mask" class="tui-drawer-mask" :class="{ 'tui-drawer-mask_show': visible }" :style="{ zIndex: maskZIndex }" @tap="handleMaskClick"></view>
		<view
			class="tui-drawer-container"
			:class="[`tui-drawer-container_${mode}`, visible ? `tui-drawer-${mode}__show` : '']"
			:style="{ zIndex: zIndex, backgroundColor: mode === 'center' ? 'transparent' : backgroundColor }"
			@touchmove.stop.prevent
		>
			<slot></slot>
		</view>
	</view>
</template>

<script setup>
import { ref, computed, watch, onMounted } from 'vue'

const emit = defineEmits(['update:modelValue', 'open', 'close'])

const props = defineProps({
	modelValue: {
		type: Boolean,
		default: false
	},
	// 此为内部参数，不在文档对外使用，为了解决Picker和keyboard等融合了弹窗的组件
	// 对v-model双向绑定多层调用造成报错不能修改props值的问题
	popup: {
		type: Boolean,
		default: true
	},
	mask: {
		type: Boolean,
		default: true
	},
	maskClosable: {
		type: Boolean,
		default: true
	},
	// left right bottom top center
	mode: {
		type: String,
		default: 'center'
	},
	//drawer z-index
	zIndex: {
		type: [Number, String],
		default: 9999
	},
	//mask z-index
	maskZIndex: {
		type: [Number, String],
		default: 9998
	},
	backgroundColor: {
		type: String,
		default: '#fff'
	}
})

const visible = computed({
	get() {
		return props.modelValue
	},
	set(val) {
		if (props.popup) {
			emit('update:modelValue', val)
		}
	}
})

watch(
	() => props.modelValue,
	nVal => {
		if (nVal) {
			open()
		} else {
			close()
		}
	}
)

const open = () => {
	emit('open')
}

const close = () => {
	emit('close')
}

const handleMaskClick = () => {
	if (!props.maskClosable) {
		return
	}
	visible.value = false
	close()
}
</script>

<style lang="scss" scoped>
.tui-drawer {
}

.tui-drawer-mask {
	opacity: 0;
	visibility: hidden;
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	bottom: 0;
	background-color: rgba(0, 0, 0, 0.6);
	transition: all 0.3s ease-in-out;
	backdrop-filter: blur(5px);
	z-index: 9998;
}

.tui-drawer-mask_show {
	display: block;
	visibility: visible;
	opacity: 1;
}

.tui-drawer-container {
	position: fixed;
	left: 50%;
	top: 0;
	transform: translate3d(-50%, -50%, 0);
	transform-origin: center;
	transition: all 0.3s ease-in-out;
	opacity: 0;
	overflow-y: scroll;
	-webkit-overflow-scrolling: touch;
	z-index: 9999;
}

.tui-drawer-container_center {
	min-width: 100rpx;
	min-height: 100rpx;
	left: 50%;
	top: 50%;
	display: flex;
	flex-direction: column;
	justify-content: center;
	align-items: center;
	opacity: 0;
	visibility: hidden;
	transform-origin: center;
	transition: all 0.3s ease-in-out;
	transform: translate3d(-50%, -50%, 0);
}

.tui-drawer-container_left {
	left: 0;
	top: 50%;
	transform: translate3d(-100%, -50%, 0);
}

.tui-drawer-container_right {
	right: 0;
	top: 50%;
	left: auto;
	transform: translate3d(100%, -50%, 0);
}

.tui-drawer-container_bottom,
.tui-drawer-container_top {
	width: 100%;
	height: auto !important;
	min-height: 20rpx;
	left: 0;
	right: 0;
	transform-origin: center;
	transition: all 0.3s ease-in-out;
}

.tui-drawer-container_bottom {
	bottom: 0;
	top: auto;
	transform: translate3d(0, 100%, 0);
	border-radius: 20rpx 20rpx 0 0;
}

.tui-drawer-container_top {
	border-radius: 0 0 20rpx 20rpx;
	transform: translate3d(0, -100%, 0);
}

.tui-drawer-center__show {
	opacity: 1;
	visibility: visible;
}

.tui-drawer-left__show,
.tui-drawer-right__show {
	opacity: 1;
	transform: translate3d(0, -50%, 0);
}

.tui-drawer-top__show,
.tui-drawer-bottom__show {
	opacity: 1;
	transform: translate3d(0, 0, 0);
}
</style>
